package org.hashdb.client.manager;

import org.hashdb.client.cmd.CommandExecutorDispatcher;
import org.hashdb.client.config.AppConfig;
import org.hashdb.client.console.AppConsoleReader;
import org.hashdb.client.net.nio.Client;
import org.hashdb.client.util.event.AbstractEventEngin;
import org.jetbrains.annotations.NotNull;

import java.nio.channels.SocketChannel;

/**
 * Date: 2024/1/19 14:53
 *
 * @author huanyuMake-pecdle
 * @version 0.0.1
 */
public class NioAppContext extends AbstractEventEngin<NioAppContext> implements AppContext, AutoCloseable {

    protected static final AppConfig config = AppConfig.getInstance();
    private static NioAppContext instance;
    private final AppConsoleReader reader;
    private CommandExecutorDispatcher dispatcher;
    private Client client;

    @NotNull
    public static NioAppContext instance() {
        if (instance == null) {
            throw new IllegalStateException();
        }
        return instance;
    }

    public static NioAppContext singletonIfNeeded(AppConsoleReader reader) {
        if (instance == null) {
            instance = new NioAppContext(reader);
            config.setAppContext(instance);
        }
        return instance;
    }

    private NioAppContext(AppConsoleReader reader) {
        this.reader = reader;
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                close();
                System.out.println("----------Bye!----------");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }));
    }

    public CommandExecutorDispatcher dispatcher() {
        if (dispatcher == null) {
            dispatcher = new CommandExecutorDispatcher(this);
        }
        return dispatcher;
    }

    @Override
    public String getUser() {
        return client.getUser();
    }

    @Override
    public SocketChannel activeConnection() {
        throw new UnsupportedOperationException();
    }

    @Override
    public AppConsoleReader reader() {
        return reader;
    }

    @Override
    public void close() {

    }

    public Client client() {
        if (client == null) {
            client = new Client(this);
        }
        return client;
    }
}
